import { 
  ScheduleItem, 
  Conflict, 
  ConflictSuggestion,
  AgendaItem 
} from '@/types';
import { agendaItems } from '@/data/agenda';

// 检查两个时间段是否重叠
const hasTimeOverlap = (
  start1: Date, 
  end1: Date, 
  start2: Date, 
  end2: Date
): boolean => {
  return start1 < end2 && start2 < end1;
};

// 计算两个地点之间的换场时间（分钟）
const getLocationChangeTime = (location1: string, location2: string): number => {
  // 简化的地点换场时间计算
  if (location1 === location2) return 0;
  
  const locationMap: Record<string, number> = {
    '云栖小镇国际会展中心主会场': 0,
    'AI专场会议室A': 5,
    '云原生专场会议室B': 5,
    '云栖小镇餐厅': 10,
    '工作坊教室C': 8,
    '大数据专场会议室D': 6,
    '安全专场会议室E': 7,
    'DevOps专场会议室F': 6,
    '移动开发专场会议室G': 8,
    '区块链专场会议室H': 9,
    'IoT展示区': 15,
    '前端专场会议室I': 7,
    '企业架构专场会议室J': 10,
    '数据库专场会议室K': 8,
    '低代码专场会议室L': 9,
    '开源专场会议室M': 10,
    '职业发展专场会议室N': 12
  };

  const time1 = locationMap[location1] || 15;
  const time2 = locationMap[location2] || 15;
  
  // 返回两个地点间的平均换场时间，最少10分钟
  return Math.max(10, Math.abs(time1 - time2) + 5);
};

// 检测时间冲突
export const detectTimeConflicts = (scheduleItems: ScheduleItem[]): Conflict[] => {
  const conflicts: Conflict[] = [];
  
  // 按开始时间排序
  const sortedItems = [...scheduleItems].sort(
    (a, b) => a.agendaItem.startTime.getTime() - b.agendaItem.startTime.getTime()
  );

  for (let i = 0; i < sortedItems.length; i++) {
    for (let j = i + 1; j < sortedItems.length; j++) {
      const item1 = sortedItems[i];
      const item2 = sortedItems[j];

      // 检查时间重叠
      const hasOverlap = hasTimeOverlap(
        item1.agendaItem.startTime,
        item1.agendaItem.endTime,
        item2.agendaItem.startTime,
        item2.agendaItem.endTime
      );

      if (hasOverlap) {
        // 直接时间冲突
        const suggestions = generateTimeConflictSuggestions([item1, item2]);
        
        conflicts.push({
          id: `conflict-${item1.id}-${item2.id}`,
          type: 'time_overlap',
          items: [item1, item2],
          severity: 'critical',
          suggestions
        });
      } else {
        // 检查换场时间是否充足
        const timeBetween = item2.agendaItem.startTime.getTime() - item1.agendaItem.endTime.getTime();
        const timeBetweenMinutes = timeBetween / (1000 * 60);
        const requiredChangeTime = getLocationChangeTime(
          item1.agendaItem.location, 
          item2.agendaItem.location
        );

        if (timeBetweenMinutes < requiredChangeTime) {
          const suggestions = generateChangeTimeSuggestions([item1, item2], requiredChangeTime);
          
          conflicts.push({
            id: `conflict-change-${item1.id}-${item2.id}`,
            type: 'location_distance',
            items: [item1, item2],
            severity: timeBetweenMinutes < requiredChangeTime / 2 ? 'high' : 'medium',
            suggestions
          });
        }

        // 检查是否缺少休息时间
        if (timeBetweenMinutes < 10 && item1.agendaItem.location === item2.agendaItem.location) {
          const suggestions = generateBreakTimeSuggestions();
          
          conflicts.push({
            id: `conflict-break-${item1.id}-${item2.id}`,
            type: 'no_break_time',
            items: [item1, item2],
            severity: 'low',
            suggestions
          });
        }
      }
    }
  }

  return conflicts;
};

// 生成时间冲突解决建议
const generateTimeConflictSuggestions = (items: ScheduleItem[]): ConflictSuggestion[] => {
  const suggestions: ConflictSuggestion[] = [];
  
  // 建议移除优先级较低的项目
  const lowerPriorityItem = items.reduce((prev, current) => {
    const priorityScore = { high: 3, medium: 2, low: 1 };
    return priorityScore[prev.priority] < priorityScore[current.priority] ? prev : current;
  });

  suggestions.push({
    type: 'remove_item',
    description: `移除优先级较低的会议："${lowerPriorityItem.agendaItem.title}"`
  });

  // 寻找替代会议
  const conflictTags = items.flatMap(item => item.agendaItem.tags);
  const alternatives = agendaItems.filter(agenda => {
    // 不在当前冲突列表中，且有相关标签
    const notInConflict = !items.some(item => item.agendaItem.id === agenda.id);
    const hasRelevantTags = agenda.tags.some(tag => conflictTags.includes(tag));
    
    // 检查时间是否与其他已选会议冲突
    const hasTimeConflictWithSchedule = items.some(item => 
      item.agendaItem.id !== agenda.id && hasTimeOverlap(
        item.agendaItem.startTime,
        item.agendaItem.endTime,
        agenda.startTime,
        agenda.endTime
      )
    );

    return notInConflict && hasRelevantTags && !hasTimeConflictWithSchedule;
  }).slice(0, 3);

  if (alternatives.length > 0) {
    suggestions.push({
      type: 'replace_item',
      description: `替换为相关主题的其他会议`,
      alternativeItems: alternatives
    });
  }

  return suggestions;
};

// 生成换场时间不足的解决建议
const generateChangeTimeSuggestions = (
  items: ScheduleItem[], 
  requiredTime: number
): ConflictSuggestion[] => {
  const suggestions: ConflictSuggestion[] = [];

  suggestions.push({
    type: 'remove_item',
    description: `建议移除其中一个会议，确保有足够的${requiredTime}分钟换场时间`
  });

  // 寻找同地点的替代会议
  const firstLocation = items[0].agendaItem.location;
  const alternatives = agendaItems.filter(agenda => {
    const notInConflict = !items.some(item => item.agendaItem.id === agenda.id);
    const sameLocation = agenda.location === firstLocation;
    const timeAfter = agenda.startTime >= items[0].agendaItem.endTime;
    
    return notInConflict && sameLocation && timeAfter;
  }).slice(0, 3);

  if (alternatives.length > 0) {
    suggestions.push({
      type: 'replace_item',
      description: `选择同地点的其他会议，减少换场时间`,
      alternativeItems: alternatives
    });
  }

  return suggestions;
};

// 生成休息时间不足的解决建议
const generateBreakTimeSuggestions = (): ConflictSuggestion[] => {
  return [
    {
      type: 'adjust_time',
      description: '建议在两个会议之间安排10-15分钟休息时间，保持良好的参会状态'
    }
  ];
};

// 检查单个新增项目是否与现有日程冲突
export const checkItemConflicts = (
  newItem: AgendaItem, 
  existingSchedule: ScheduleItem[]
): Conflict[] => {
  const tempScheduleItem: ScheduleItem = {
    id: 'temp',
    agendaItem: newItem,
    priority: 'medium'
  };

  return detectTimeConflicts([...existingSchedule, tempScheduleItem])
    .filter(conflict => conflict.items.some(item => item.id === 'temp'));
};

// 获取建议的最佳日程安排（自动解决冲突）
export const getOptimizedSchedule = (scheduleItems: ScheduleItem[]): ScheduleItem[] => {
  const conflicts = detectTimeConflicts(scheduleItems);
  
  if (conflicts.length === 0) {
    return scheduleItems;
  }

  let optimizedSchedule = [...scheduleItems];

  // 处理严重冲突（直接时间重叠）
  const criticalConflicts = conflicts.filter(c => c.severity === 'critical');
  
  for (const conflict of criticalConflicts) {
    if (conflict.type === 'time_overlap') {
      // 移除优先级较低的项目
      const itemsToRemove = conflict.items.sort((a, b) => {
        const priorityScore = { high: 3, medium: 2, low: 1 };
        return priorityScore[a.priority] - priorityScore[b.priority];
      }).slice(0, 1);

      optimizedSchedule = optimizedSchedule.filter(item => 
        !itemsToRemove.some(remove => remove.id === item.id)
      );
    }
  }

  // 递归优化直到没有严重冲突
  const remainingConflicts = detectTimeConflicts(optimizedSchedule);
  const remainingCritical = remainingConflicts.filter(c => c.severity === 'critical');
  
  if (remainingCritical.length > 0) {
    return getOptimizedSchedule(optimizedSchedule);
  }

  return optimizedSchedule;
};

// 获取日程统计信息
export const getScheduleStats = (scheduleItems: ScheduleItem[]) => {
  const conflicts = detectTimeConflicts(scheduleItems);
  const totalDuration = scheduleItems.reduce((sum, item) => {
    const duration = item.agendaItem.endTime.getTime() - item.agendaItem.startTime.getTime();
    return sum + duration;
  }, 0);

  const categories = [...new Set(scheduleItems.map(item => item.agendaItem.category))];
  const tags = [...new Set(scheduleItems.flatMap(item => item.agendaItem.tags))];

  return {
    totalItems: scheduleItems.length,
    totalConflicts: conflicts.length,
    criticalConflicts: conflicts.filter(c => c.severity === 'critical').length,
    totalDurationHours: Math.round(totalDuration / (1000 * 60 * 60) * 10) / 10,
    uniqueCategories: categories.length,
    uniqueTags: tags.length,
    categories,
    tags
  };
};